/**
 * @class MapService.Layer.Group
 * @extends OpenLayers.Class
 * Utilizado para agrupar layers.
 * 
 * Exemplo de uso:
 * 
 *     var mub = new MapService.Layer.Group({
 * 	    name: "Mub"
 *     });
 *     
 *     mapService.map.addGroup(null, mub);
 *     
 *     var estado = new OpenLayers.Layer.WMS(
 * 	    "Estado",
 * 	    "http://desenvolvimento.digicade.com.br:8080/geoserver/wms", 
 * 	    {
 * 		    layers      : "DGMUBVIEW:PLG_UF",
 * 		    transparent : true
 * 	    },{
 * 		    group                  : mub,
 * 		    isBaseLayer            : false,
 * 		    singleTile             : true,
 * 		    visibility             : true,
 * 		    scaleRanges            : [new MapService.Layer.ScaleRange({
 * 			    minScale : 0,
 * 			    maxScale : 1000000000,
 * 			    themes   : [new MapService.Layer.Theme({
 * 				    icon    : "images/icone/uf.png",
 * 				    legend  : "Default"
 * 			    })]
 * 		    })]
 * 	    }
 *     );
 *     
 *     mapService.map.addLayer(estado);
 *     
 */
MapService.Layer.Group = OpenLayers.Class({
	/**
	 * @cfg {String}
	 */
    id          : null,

	/**
	 * @cfg {String}
	 */
    name        : null,
    
	/**
	 * @property {MapService.Layer.Group}
	 * @readonly
	 */
    parent      : null,
    
	/**
	 * @property {MapService.Layer.Group[]}
	 * @readonly
	 */
    children    : null,
    
	/**
	 * @property {Boolean}
	 * @readonly
	 * Utilizar a função {@link MapService.Layer.Group#setChecked setChecked} para modificar o valor desta propriedade.
	 */
    checked     : true,
    
	/**
	 * @cfg {Boolean}
	 */
    expanded    : false,
    
    initialize : function(options) {
    	var me = this;
    	
    	me.children = [];
    	
    	OpenLayers.Util.extend(me, options);
    	
        if (me.id == null) {
        	me.id = OpenLayers.Util.createUniqueID(me.CLASS_NAME + "_");
        }
        
        me.events = new OpenLayers.Events(me);
    },
    
	/**
	 * Habilita/Desabilita todos os layers que são deste grupo/subgrupo.
	 */
    setChecked : function(checked){
    	var me = this;
    	
    	if(me.checked !== checked){
    		me.checked = checked;
    		
    		
    		var checkLayerVisibility = function(group){
	    		var layers = me.map.layers;
	        	for(var i = 0; i < layers.length; i++){
	        		var layer = layers[i];
	        		
	        		if(layer.group === group){
	        			if (!layer.isBaseLayer) {
	    					var inRange = layer.calculateInRange();
	    					if (layer.inRange != inRange) {
	    						layer.inRange = inRange;
	    						layer.display(inRange);
	    						
	    						layer.map.events.triggerEvent("changelayer", {
	    							layer    : layer, 
	    							property : "visibility"
	    						});
	    					}
	    				}
	        		}
	        	}
	        	
	        	for(var i = 0; i < group.children.length; i++){
	        		checkLayerVisibility(group.children[i]);
        		}
    		};
    		
    		checkLayerVisibility(me);
    		
    		
    		me.map.events.triggerEvent("changegroup", {
				group    : me,
				property : "visibility"
			});
    	}
    },
    
	/**
	 * Percorre todos os grupos filhos/subfilhos recursivamente, A PARTIR deste grupo.
	 * 
	 * Exemplo de uso:
	 * 
	 *     var mub = new OpenLayers.Group({
	 *     	name: "Mub"
	 *     });
	 *     
	 *     mapService.map.addGroup(null, mub);
	 *     
	 *     mub.cascadeBy(function(grupo){
	 *     	console.log(grupo);
	 *     });
	 *     
	 */
    cascadeBy : function(fn, scope, args) {
    	var me = this;
    	
    	if (fn.apply(scope || me, args || [me]) !== false) {
            var children = me.children,
                length      = children.length,
                i;
            
            for (i = 0; i < length; i++) {
            	children[i].cascadeBy(fn, scope, args);
            }
        }
    },

	/**
	 * Percorre todos os grupos filhos deste grupo, SOMENTE os filhos deste grupo.
	 * 
	 * Exemplo de uso:
	 * 
	 *     var mub = new OpenLayers.Group({
	 *     	name: "Mub"
	 *     });
	 *     
	 *     mapService.map.addGroup(null, mub);
	 *     
	 *     mub.eachChild(function(grupo){
	 *     	console.log(grupo);
	 *     });
	 *     
	 */
    eachChild : function(fn, scope, args) {
    	var me = this;
    	
        var children = me.children,
            length   = children.length,
            i;

        for (i = 0; i < length; i++) {
            if (fn.apply(scope || this, args || [children[i]]) === false) {
                break;
            }
        }
    },
    
    CLASS_NAME: "MapService.Layer.Group"
});